package com.psdi.element;

import com.psdi.Main;
import com.psdi.manager.ElementManager;
import com.psdi.manager.EnemySystem;
import com.psdi.manager.GameLoader;
import com.psdi.manager.GameManager;
import com.psdi.physics.Collider;
import com.psdi.physics.CollisionSystem;
import com.psdi.window.GameJFrame;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class Boss extends ElementObject implements Collider {
    private float hp;
    private float Maxhp;
    private boolean condition2 = false;
    private final float atk=3;
    private int firenum = 10;
    private float firecolddown= 5f;
    private float firecool;
    private float staytime = 11f;
    private float staytimes;
    private float atktime = 2f;
    private float atktimes;
    private float hurtanimtime = 2f;
    Vector2D direction = Vector2D.DOWN; //敌人移动方向
    private final Vector2D[] directions = {
            Vector2D.LEFT, Vector2D.RIGHT, Vector2D.UP, Vector2D.DOWN
    }; // 敌人可能的移动方向
    private final Random random = new Random();
    public Boss(){};
    public ElementObject creatBoss(Position pos ,float Hp, Size size){
        this.tag=Tag.BOSS;
        this.image = GameLoader.iconMap2.get(tag.toString()).get(0);
        this.transform = new Transform(pos,new Rotation(),size);
        CollisionSystem.INSTANCE.addElement(this);
        Maxhp = Hp;
        hp = Maxhp;
        return this;
    }

    @Override
    public Size colliderSize() {
        return transform.size;
    }

    @Override
    public Position colliderPosition() {
        return transform.position;
    }

    @Override
    public Tag colliderTag() {
        return tag;
    }

    @Override
    public Set<Tag> colliderFilterTag() {
        Set<Tag> set = new  HashSet<>();
        set.add(Tag.MAP);
        set.add(Tag.BOSSBULLET);
        return set;
    }

    @Override
    public void onCollisionStay(ElementObject other) {
        if (other instanceof Bullet || other instanceof Knife ||other instanceof KnifeAirflow) {
            setAlive(checkconditon()); // 被子弹击中时，检测状态
            if(hurtanimtime<=0){
                GameLoader.LoadBoom(new Position(random.nextInt(transform.size.width)+transform.position.x,random.nextInt(transform.size.height)+transform.position.y),new Size(30,30));
                hurtanimtime = 0.8f;
            }

        } else if (other instanceof Player) {
            other.setAlive(((Player) other).checkCondition()); // 敌人碰到玩家时，玩家检测死亡
            ((Player) other).setHp(((Player) other).getHp() - atk);
            other.transform.position.add(direction.scalarMultiply(150));
        }
    }
    @Override
    public void update() {
        if (transform.position.x<-10f || transform.position.x > GameJFrame.GAME_WIDTH +10f ||
                transform.position.y < -10f|| transform.position.y > GameJFrame.GAME_HEIGHT +10f) {
            movelogic();
        }
        // 这里可以添加敌人的行为逻辑，例如移动、攻击等
        hurtanimtime -= Main.DELTA_TIME;
        atktimes -= Main.DELTA_TIME;
        if(atktimes<=0){
            atk();
        }
        staytimes -= Main.DELTA_TIME;
        if(staytimes<=0){
            movelogic();//Boss的移动逻辑
        } else if (staytimes > 0 && staytimes <=4) {
            transform.position.add(direction.scalarMultiply(3f));
        }
        updateImage();
        firecool -= Main.DELTA_TIME;
        if(firecool <=0){
            for (int i = 0;i<firenum;i++){
                firebullet();
            }
        }
    }
    private void atk(){
        Position pos = transform.center();
        pos.add(direction.scalarMultiply(50));
        GameLoader.LoadBossBullet(pos,direction,new Size(100,100));
        atktimes = atktime;
    }
    private void changemodel(){
        if(condition2){
            firenum = 14;
            firecolddown = 2f;
            staytime = 6f;
            atktime = 1f;
        }
    }
    private boolean checkconditon(){
        if(hp <= 0){
            GameManager.gameManager.killNum++;
            return false;
        } else if (hp <= Maxhp/2) {
        condition2 = true;
        changemodel();
        return false;
        } else return true;
    }
    private void firebullet(){
        Position pos = new Position(0,0);
        if(direction.x == -1){
            pos.y = random.nextInt(GameJFrame.GAME_HEIGHT)-50;
            pos.x = GameJFrame.GAME_WIDTH-50;
        } else if (direction.x == 1) {
            pos.y = random.nextInt(GameJFrame.GAME_HEIGHT)-50;
            pos.x = 0;
        } else if (direction.y ==-1) {
            pos.x = random.nextInt(GameJFrame.GAME_WIDTH)-50;
            pos.y = GameJFrame.GAME_HEIGHT - 50;
        } else if (direction.y == 1) {
            pos.x = random.nextInt(GameJFrame.GAME_WIDTH)-50;
            pos.y = 0;
        }
        GameLoader.LoadBossBullet(pos,direction,new Size(50,50));
        firecool = firecolddown;
    }
    private void movelogic(){
        Position[] positions = {
                new Position(GameJFrame.GAME_WIDTH-transform.size.height , (float) GameJFrame.GAME_HEIGHT /2 - (float) transform.size.width /2),
                new Position(0, (float) GameJFrame.GAME_HEIGHT /2 - (float) transform.size.height /2),
                new Position((float) GameJFrame.GAME_WIDTH /2 - (float) transform.size.width /2,GameJFrame.GAME_HEIGHT - transform.size.height) ,
                new Position((float) GameJFrame.GAME_WIDTH /2 - (float) transform.size.width /2, 0)
        };
        int order = random.nextInt(4);
        direction = directions[order];
        transform.position = positions[order];
        staytimes = staytime;
    }
    private int controldir(){
        if (direction.equals(Vector2D.LEFT)) {
            return 90;
        } else if (direction.equals(Vector2D.UP)) {
            return 180;
        } else if (direction.equals(Vector2D.RIGHT)) {
            return 270;
        }
        else return 0;
    }
    @Override
    protected void updateImage() {
        transform.rotation.z = controldir();
        setImage(GameLoader.iconMap2.get(tag.toString()).get(0));
    }

    @Override
    public void onDestroy() {
        GameLoader.LoadBoom(this.transform.position,this.transform.size);
    }

    public void setHp(float hp) {
        this.hp = hp;
    }

    public float getHp() {
        return hp;
    }
}
